#include "SqlReader.h"
#include "Fdo.h"

MgdSqlDataReader::MgdSqlDataReader(FdoISQLDataReader* reader)
{
	m_reader = FDO_SAFE_ADDREF(reader);
}

MgdSqlDataReader::~MgdSqlDataReader() 
{
	FDO_SAFE_RELEASE(m_reader);
} 

bool MgdSqlDataReader::ReadNext() { return m_reader->ReadNext(); }

INT32 MgdSqlDataReader::GetPropertyCount() { return m_reader->GetColumnCount(); }

STRING MgdSqlDataReader::GetPropertyName(INT32 index) 
{ 
	FdoString* name = m_reader->GetColumnName(index);
	return STRING(name);
}

INT32 MgdSqlDataReader::GetPropertyType(CREFSTRING propertyName) 
{ 
	return m_reader->GetPropertyType(propertyName.c_str());
}

INT32 MgdSqlDataReader::GetPropertyType(INT32 index) 
{ 
	return m_reader->GetPropertyType(index);
}

bool MgdSqlDataReader::IsNull(CREFSTRING propertyName) 
{ 
	return m_reader->IsNull(propertyName.c_str());
}

bool MgdSqlDataReader::GetBoolean(CREFSTRING propertyName) 
{ 
	return m_reader->GetBoolean(propertyName.c_str());
}

BYTE MgdSqlDataReader::GetByte(CREFSTRING propertyName) 
{ 
	return m_reader->GetByte(propertyName.c_str());
}

MgDateTime* MgdSqlDataReader::GetDateTime(CREFSTRING propertyName) 
{ 
	Ptr<MgDateTime> mdt;
	FdoDateTime fdt = m_reader->GetDateTime(propertyName.c_str());
	mdt = new MgDateTime();
	return mdt.Detach();
}

float MgdSqlDataReader::GetSingle(CREFSTRING propertyName) 
{ 
	return m_reader->GetSingle(propertyName.c_str());
}

double MgdSqlDataReader::GetDouble(CREFSTRING propertyName) 
{ 
	return m_reader->GetDouble(propertyName.c_str());
}

INT16 MgdSqlDataReader::GetInt16(CREFSTRING propertyName) 
{ 
	return m_reader->GetInt16(propertyName.c_str());
}

INT32 MgdSqlDataReader::GetInt32(CREFSTRING propertyName) 
{ 
	return m_reader->GetInt32(propertyName.c_str());
}

INT64 MgdSqlDataReader::GetInt64(CREFSTRING propertyName) 
{ 
	return m_reader->GetInt64(propertyName.c_str());
}

STRING MgdSqlDataReader::GetString(CREFSTRING propertyName) 
{ 
	FdoString* value = m_reader->GetString(propertyName.c_str());
	return STRING(value);
}

MgByteReader* MgdSqlDataReader::GetBLOB(CREFSTRING propertyName) 
{ 
	Ptr<MgByteReader> blob;

    FdoPtr<FdoLOBValue> fdoVal = m_reader->GetLOB(propertyName.c_str());
    if (fdoVal != NULL)
    {
        FdoPtr<FdoByteArray> byteArray = fdoVal->GetData();
        if (byteArray != NULL)
        {
            FdoByte* bytes = byteArray->GetData();
            FdoInt32 len = byteArray->GetCount();
            Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)bytes,(INT32)len);
            blob = byteSource->GetReader();
        }
    }

	return blob.Detach();
}

MgByteReader* MgdSqlDataReader::GetCLOB(CREFSTRING propertyName)
{ 
	Ptr<MgByteReader> clob;

    FdoPtr<FdoLOBValue> fdoVal = m_reader->GetLOB(propertyName.c_str());
    if (fdoVal != NULL)
    {
        FdoPtr<FdoByteArray> byteArray = fdoVal->GetData();
        if (byteArray != NULL)
        {
            FdoByte* bytes = byteArray->GetData();
            FdoInt32 len = byteArray->GetCount();
            Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)bytes,(INT32)len);
            clob = byteSource->GetReader();
        }
    }

	return clob.Detach();
}

MgByteReader* MgdSqlDataReader::GetGeometry(CREFSTRING propertyName) 
{ 
	Ptr<MgByteReader> geom;

    FdoPtr<FdoByteArray> byteArray = m_reader->GetGeometry(propertyName.c_str());
    INT32 len = (INT32)byteArray->GetCount();
    const FdoByte* data = byteArray->GetData();

    if (data != NULL)
    {
        Ptr<MgByte> mgBytes = new MgByte((BYTE_ARRAY_IN)data, len);
        Ptr<MgByteSource> bSource = new MgByteSource(mgBytes);
        bSource->SetMimeType(MgMimeType::Agf);
        geom = bSource->GetReader();
    }

	return geom.Detach();
}

MgRaster* MgdSqlDataReader::GetRaster(CREFSTRING propertyName) 
{ 
	throw new MgInvalidPropertyTypeException(L"MgdSqlDataReader::GetRaster",
        __LINE__, __WFILE__, NULL, L"", NULL);
}

INT32 MgdSqlDataReader::GetPropertyIndex(CREFSTRING propertyName) 
{ 
	return m_reader->GetColumnIndex(propertyName.c_str());
}

bool MgdSqlDataReader::IsNull(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return IsNull(propertyName);
}

bool MgdSqlDataReader::GetBoolean(INT32 index) 
{
	STRING propertyName = GetPropertyName(index);
    return GetBoolean(propertyName);
}

BYTE MgdSqlDataReader::GetByte(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetByte(propertyName);
}

MgDateTime* MgdSqlDataReader::GetDateTime(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetDateTime(propertyName);
}

float MgdSqlDataReader::GetSingle(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetSingle(propertyName);
}

double MgdSqlDataReader::GetDouble(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetDouble(propertyName);
}

INT16 MgdSqlDataReader::GetInt16(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetInt16(propertyName);
}

INT32 MgdSqlDataReader::GetInt32(INT32 index)
{ 
	STRING propertyName = GetPropertyName(index);
    return GetInt32(propertyName);
}

INT64 MgdSqlDataReader::GetInt64(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetInt64(propertyName);
}

STRING MgdSqlDataReader::GetString(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetString(propertyName);
}

MgByteReader* MgdSqlDataReader::GetBLOB(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetBLOB(propertyName);
}

MgByteReader* MgdSqlDataReader::GetCLOB(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetCLOB(propertyName);
}

MgByteReader* MgdSqlDataReader::GetGeometry(INT32 index) 
{ 
	STRING propertyName = GetPropertyName(index);
    return GetGeometry(propertyName);
}

MgRaster* MgdSqlDataReader::GetRaster(INT32 index) 
{ 
	throw new MgInvalidPropertyTypeException(L"MgdSqlDataReader::GetRaster",
        __LINE__, __WFILE__, NULL, L"", NULL);
}

void MgdSqlDataReader::Close() { m_reader->Close(); }

INT32 MgdSqlDataReader::GetReaderType() 
{ 
	return MgReaderType::FeatureReader;
}

//EXTERNAL_API:

MgByteReader* MgdSqlDataReader::ToXml() 
{ 
	throw new MgNotImplementedException(L"MgdSqlDataReader::ToXml", __LINE__, __WFILE__, NULL, L"", NULL);
}

//INTERNAL_API:

const wchar_t* MgdSqlDataReader::GetString(CREFSTRING propertyName, INT32& length) 
{ 
	throw new MgNotImplementedException(L"MgdSqlDataReader::ToXml", __LINE__, __WFILE__, NULL, L"", NULL);
}

void MgdSqlDataReader::Serialize(MgStream* stream) 
{ 
	throw new MgNotImplementedException(L"MgdSqlDataReader::Serialize", __LINE__, __WFILE__, NULL, L"", NULL);
}

void MgdSqlDataReader::Deserialize(MgStream* stream) 
{ 
	throw new MgNotImplementedException(L"MgdSqlDataReader::Deserialize", __LINE__, __WFILE__, NULL, L"", NULL);
}